﻿using System;
using System.Linq;
using Csla;
using Csla.Data;
using BizControl.DalLinq;
using BizControl.Library.Security;
using BizControl.Library.BusinessObjects.Models;
using BizControl.Library.BusinessObjects.People;
using BizControl.Library.Criterias;
using BizControl.Resources;
using System.Security;
using System.Collections.Generic;

namespace BizControl.Library.BusinessObjects.Activities
{
  [Serializable()]
  public class ActivityList : ReadOnlyListBase<ActivityList, ActivityInfo>
  {
    internal void AllowChange()
    {
      IsReadOnly = false;
    }

    internal void ForbidChange()
    {
      IsReadOnly = true;
    }

    #region  Factory Methods

    public static ActivityList NewActivityList()
    {
      return DataPortal.Create<ActivityList>();
    }

    public static ActivityList GetActivityList(PersonBO person, ModelBO model)
    {
      return DataPortal.Fetch<ActivityList>(new PersonAndModelCriteria(person, model));
    }

    public static ActivityList GetActivityList()
    {
      var person = ((BizControlPrincipal)ApplicationContext.User).Person;
      var model = ((BizControlPrincipal)ApplicationContext.User).Model;
      return DataPortal.Fetch<ActivityList>(new PersonAndModelCriteria(person, model));
    }

    #endregion

    #region  Data Access

    private void DataPortal_Create()
    {
    }

    private void DataPortal_Fetch(PersonAndModelCriteria criteria)
    {
      if (criteria.Model == null) throw new ArgumentNullException(ExceptionsMessages.ModelNullReference);
      if (criteria.Person == null) throw new ArgumentNullException(ExceptionsMessages.PersonNullReference);
      var currentUser = SecurityChecks.GetCurrentUser();
      RaiseListChangedEvents = false;
      using (var ctx = ContextManager<BusinessControl2DataContext>.GetManager(Database.BizControlDB))
      {
        var distinctedData = (from a in ctx.DataContext.Activities
                             from p in ctx.DataContext.Participants
                             where !a.IsDeleted 
                             && a.Model == criteria.Model.ModelId
                             && ((a.ActivityId == p.Activity && p.Person == criteria.Person.PersonId && !p.IsDeleted)
                             || a.CreatedBy == currentUser.PersonId)
                             select a).Distinct();
        var data = from a in distinctedData
                   select new ActivityInfo(a);
        IsReadOnly = false;
        this.AddRange(data);
        IsReadOnly = true;
      }
      RaiseListChangedEvents = true;
    }

    #endregion

  }
}
